package com.bto.solar.work.service.biz_stage_handler;

import com.bto.solar.work.common.BizException;
import com.bto.solar.work.constant.BizStageEnum;
import com.bto.solar.work.constant.BizTaskEnum;
import com.bto.solar.work.constant.BizTaskStateEnum;
import com.bto.solar.work.constant.Constants;
import com.bto.solar.work.dao.IOrderBaseService;
import com.bto.solar.work.entity.OrderState;
import com.bto.solar.work.lease.LeaseApi;
import com.bto.solar.work.service.BtoDeviceService;
import com.bto.solar.work.service.BtoLeaseReviewService;
import com.bto.solar.work.service.BtoOrderStateService;
import com.bto.solar.work.utils.NullUtils;
import com.bto.solar.work.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;

/**
 * @author 王小波
 * @description: 施工
 * @date 2023/7/24 17:05
 */

@Slf4j
@Component
public class ShiGongStageHandler implements StageHandler {
    private String stageId = BizStageEnum.CONSTRUCT.getStageId();

    public List<String> allConstructSBXXTasks = Arrays.asList(null,
            BizTaskEnum.TASK_SBXX_ZUJIAN.getTaskId(), BizTaskEnum.TASK_SBXX_NBQ.getTaskId(),
            BizTaskEnum.TASK_SBXX_CJQ.getTaskId(), BizTaskEnum.TASK_SBXX_PDX.getTaskId(),
            BizTaskEnum.TASK_SBXX_ZLDL.getTaskId(), BizTaskEnum.TASK_SBXX_ZHIJIA.getTaskId()
    );

    public List<String> allConstructTasks = Arrays.asList(null,
            BizTaskEnum.TASK_SGXX.getTaskId(), BizTaskEnum.TASK_SGYXJXX.getTaskId(),
            BizTaskEnum.TASK_SBXX.getTaskId(),
            BizTaskEnum.TASK_SBXX_ZUJIAN.getTaskId(), BizTaskEnum.TASK_SBXX_NBQ.getTaskId(),
            BizTaskEnum.TASK_SBXX_CJQ.getTaskId(), BizTaskEnum.TASK_SBXX_PDX.getTaskId(),
            BizTaskEnum.TASK_SBXX_ZLDL.getTaskId(), BizTaskEnum.TASK_SBXX_ZHIJIA.getTaskId()
    );


    @Autowired
    private IOrderBaseService orderService;
    @Autowired
    private BtoOrderStateService btoOrderStateService;
    @Autowired
    private DesignStageHandler designStageHandler;
    @Autowired
    private BtoDeviceService btoDeviceService;
    @Autowired
    private BingWangStageHandler bingWangStageHandler;
    @Autowired
    private LeaseApi leaseApi;
    @Autowired
    private BtoLeaseReviewService btoLeaseReviewService;

    /**
     * 施工阶段同时开启：
     * 施工信息、设备信息、施工影像信息、备案证信息
     * 设备信息：组件、逆变器、支架
     */
    @Override
    public void createNewInitState(String orderId, String stageId, String taskId) {

        //施工信息
        btoOrderStateService.createOrderState(orderId, BizStageEnum.CONSTRUCT.getStageId(), BizTaskEnum.TASK_SGXX.getTaskId(),
                BizTaskStateEnum.WAITING_FILLED.getStateId());
        //设备信息
        btoOrderStateService.createOrderState(orderId, BizStageEnum.CONSTRUCT.getStageId(), BizTaskEnum.TASK_SBXX.getTaskId(),
                BizTaskStateEnum.WAITING_FILLED.getStateId());
        btoOrderStateService.createOrderState(orderId, BizStageEnum.CONSTRUCT.getStageId(), BizTaskEnum.TASK_SBXX_ZUJIAN.getTaskId(),
                BizTaskStateEnum.WAITING_FILLED.getStateId());
        btoOrderStateService.createOrderState(orderId, BizStageEnum.CONSTRUCT.getStageId(), BizTaskEnum.TASK_SBXX_NBQ.getTaskId(),
                BizTaskStateEnum.WAITING_FILLED.getStateId());
        btoOrderStateService.createOrderState(orderId, BizStageEnum.CONSTRUCT.getStageId(), BizTaskEnum.TASK_SBXX_CJQ.getTaskId(),
                BizTaskStateEnum.WAITING_FILLED.getStateId());
        btoOrderStateService.createOrderState(orderId, BizStageEnum.CONSTRUCT.getStageId(), BizTaskEnum.TASK_SBXX_PDX.getTaskId(),
                BizTaskStateEnum.WAITING_FILLED.getStateId());
        btoOrderStateService.createOrderState(orderId, BizStageEnum.CONSTRUCT.getStageId(), BizTaskEnum.TASK_SBXX_ZLDL.getTaskId(),
                BizTaskStateEnum.WAITING_FILLED.getStateId());
        btoOrderStateService.createOrderState(orderId, BizStageEnum.CONSTRUCT.getStageId(), BizTaskEnum.TASK_SBXX_ZHIJIA.getTaskId(),
                BizTaskStateEnum.WAITING_FILLED.getStateId());
        //施工影像
        btoOrderStateService.createOrderState(orderId, BizStageEnum.CONSTRUCT.getStageId(), BizTaskEnum.TASK_SGYXJXX.getTaskId(),
                BizTaskStateEnum.WAITING_FILLED.getStateId());
        //备案证信息
        //btoOrderStateService.createOrderState(orderId, BizStageEnum.CONSTRUCT.getStageId(), BizTaskEnum.TASK_BAZXX.getTaskId(),
        //        BizTaskStateEnum.WAITING_FILED.getStateId());

        //施工阶段-总状态
        btoOrderStateService.createOrderState(orderId, BizStageEnum.CONSTRUCT.getStageId(), this.stageId,
                BizTaskStateEnum.WAITING_FILLED.getStateId());
    }




    /**
    * 更新设备信息为待填写
     * 设计变更
    */
    public void updateToWaitingFilledState(String orderId, String stageId, String taskId) {
        btoOrderStateService.updateOrderTaskState(orderId, this.stageId, taskId, BizTaskStateEnum.WAITING_FILLED.getStateId());
        updateConstructSBXXState(orderId ,  BizTaskStateEnum.WAITING_FILLED.getStateId());
    }


    /**
     * 设计-待审核
     * 1、初次提交审核 2、审批拒绝待审核 3、设计变更待审核
     */
    @Transactional
    @Override
    public void updateToWaitingApprovalState(String orderId, String stageId, String taskId) {
        //施工综合状态-待审核
        if (BizStageEnum.CONSTRUCT.getStageId().equals(taskId)) {
            /**
             * 设计、设计变更通过
             * 需要检查施工的组件数量要和设计组件数量对比。
             * 当所有施工任务，都处于填写OK状态，触发施工审核
             */
            if(!designStageHandler.isDesignStagePass(orderId)){
                throw new BizException("设计变更未通过，无法提交审核");
            }
            if (!btoDeviceService.checkConstructDeviceZuJianCountEqualDesign(orderId)) {
                throw new BizException("施工组件数与设计不相符，无法提交审核");
            }

            //更新全部施工任务，为待审核-博通  待填写状态不允许更新
            updateAllConstructStateWaitingApprovalBto(orderId);

            btoOrderStateService.updateOrSaveOrderState(orderId, BizStageEnum.CONSTRUCT.getStageId(), this.stageId,
                    BizTaskStateEnum.WAITING_APPROVAL_BTO.getStateId(),
                    BizTaskStateEnum.FILLED_OK.getStateId(),
                    BizTaskStateEnum.WAITING_APPROVAL_BTO.getStateId(),
                    BizTaskStateEnum.WAITING_FILLED.getStateId(),
                    BizTaskStateEnum.APPROVAL_REJECT_BTO.getStateId(),
                    BizTaskStateEnum.APPROVAL_REJECT_LEASE.getStateId());

        }
        //如果提交的是设备信息  -- 填写ok
        else if (StringUtils.isNotEmpty(taskId)) {
            btoOrderStateService.updateOrSaveOrderState(orderId, BizStageEnum.CONSTRUCT.getStageId(), taskId,
                    BizTaskStateEnum.FILLED_OK.getStateId(),
                    BizTaskStateEnum.FILLED_OK.getStateId(),
                    BizTaskStateEnum.WAITING_FILLED.getStateId(),
                    BizTaskStateEnum.APPROVAL_REJECT_BTO.getStateId(),
                    BizTaskStateEnum.APPROVAL_REJECT_LEASE.getStateId());


            //提交设备信息时。检查所有设备信息，是否都填写ok
            if (taskId.contains(BizTaskEnum.TASK_SBXX.getTaskId())) {
                if (checkAllConstructDeviceInfoFilledOk(orderId)) {
                    updateConstructSBXXState(orderId, BizTaskStateEnum.FILLED_OK.getStateId());
                } else {
                    updateConstructSBXXState(orderId, BizTaskStateEnum.WAITING_FILLED.getStateId());
                }
            }
        }
    }

    @Transactional
    @Override
    public void updateToApprovalPassState(String orderId, String stageId, String taskId, String approvalType) {
        if (Constants.APPROVAL_BTO.equals(approvalType)) {
            btoOrderStateService.updateOrSaveOrderState(orderId, BizStageEnum.CONSTRUCT.getStageId(), taskId,
                    BizTaskStateEnum.APPROVAL_PASS_BTO.getStateId(),
                    BizTaskStateEnum.WAITING_APPROVAL_BTO.getStateId(), true);
            //只有审批的是设备信息，才检查所有的设备信息是否通过
            if (taskId.contains(BizTaskEnum.TASK_SBXX.getTaskId()) && checkAllConstructDeviceInfoState(orderId, BizTaskStateEnum.APPROVAL_PASS_BTO.getStateId())) {
                //所有设备信息，审批通过 设备信息审批通过
                btoOrderStateService.updateOrSaveOrderState(orderId, BizStageEnum.CONSTRUCT.getStageId(), BizTaskEnum.TASK_SBXX.getTaskId(),
                        BizTaskStateEnum.APPROVAL_PASS_BTO.getStateId(),
                        BizTaskStateEnum.WAITING_APPROVAL_BTO.getStateId());
            }
            // 博通审核（施工阶段的任务和备案证信息）全部通过 --> 越秀待审核
            updateApprovalAllPassStateBySgAndBaz(orderId);

        }
        //越秀施工审核通过
        else if (Constants.APPROVAL_LEASE.equals(approvalType)) {
            btoOrderStateService.updateOrSaveOrderState(orderId, BizStageEnum.CONSTRUCT.getStageId(), this.stageId,
                    BizTaskStateEnum.APPROVAL_PASS_LEASE.getStateId(),
                    BizTaskStateEnum.WAITING_APPROVAL_LEASE.getStateId(), true);
            //施工信息、设备信息、施工影像博通审核通过 --》越秀审核通过
            //updateAllConstructInfoLeaseApprovalState(orderId , BizTaskStateEnum.APPROVAL_PASS_LEASE.getStateId());

            updateAllConstructState(orderId, BizTaskStateEnum.APPROVAL_PASS_LEASE.getStateId(), allConstructTasks.toArray(new String[0]));

            //开启并网阶段
            bingWangStageHandler.createNewInitState(orderId, BizStageEnum.GRID_CONNECTION.getStageId(), BizTaskEnum.TASK_BWXX.getTaskId());

//            //检查施工信息和备案证信息是否越秀审核全部通过
//            if (checkAllConstructInfoState(orderId , BizTaskStateEnum.APPROVAL_PASS_LEASE.getStateId())) {
//
//            }
            //更新订单设备已经被使用
            btoDeviceService.updateOrderDevicesUsedInSto(orderId);
        }

    }


    public void updateApprovalAllPassStateBySgAndBaz(String orderId) {
        //博通审核全部通过
        if (checkAllConstructInfoState(orderId, BizTaskStateEnum.APPROVAL_PASS_BTO.getStateId())) {
            //推送越秀施工审核-10形式
            val operatingRes = leaseApi.operatingSign(orderService.getById(orderId), true);
            if (NullUtils.isNull(operatingRes)) {
                throw new BizException("推送资方施工信息审核，推送失败，请重新操作 订单{}", orderId);
            }
            val pushFileedByOne = leaseApi.isFileAndContactSyncPush(orderId, Constants.NHTF_FILE_LIST_ONE, true);
            if(!pushFileedByOne){
                throw new BizException("推送资方，农户投放，推送农户投放第一次图片失败 订单{} , 请重新操作" , orderId);
            }
            val pushFileedByTwo = leaseApi.isFileAndContactSyncPush(orderId, Constants.NHTF_FILE_LIST_TWO, true);
            if(!pushFileedByTwo){
                throw new BizException("推送资方，农户投放，推送农户投放第二次图片失败 订单{} , 请重新操作" , orderId);
            }
            val pushFileedByThree = leaseApi.isFileAndContactSyncPush(orderId, Constants.NHTF_FILE_LIST_THREE, true);
            if(!pushFileedByThree){
                throw new BizException("推送资方，农户投放，推送农户投放第三次图片失败 订单{} , 请重新操作" , orderId);
            }
            //重置越秀审核状态记录
            btoLeaseReviewService.clearLeaseReviewState(orderId, Constants.AGAIN_OPERATING_SIGN);

            //施工阶段从博通待审核 -->  越秀待审核
            btoOrderStateService.updateOrSaveOrderState(orderId, BizStageEnum.CONSTRUCT.getStageId(), this.stageId,
                    BizTaskStateEnum.WAITING_APPROVAL_LEASE.getStateId(),
                    BizTaskStateEnum.WAITING_APPROVAL_BTO.getStateId(), true);
            //更新全部任务--越秀待审核
            updateAllConstructState(orderId, BizTaskStateEnum.WAITING_APPROVAL_LEASE.getStateId(), allConstructTasks.toArray(new String[0]));

            //备案证信息从博通通过审核 --> 越秀待审核
            //btoOrderStateService.updateOrSaveOrderState(orderId, BizStageEnum.BAZING.getStageId(), BizTaskEnum.TASK_BAZXX.getTaskId(),
            //        BizTaskStateEnum.WAITING_APPROVAL_LEASE.getStateId(),
            //        BizTaskStateEnum.APPROVAL_PASS_BTO.getStateId(), true);
        }
    }

    @Override
    public void updateToApprovalRejectState(String orderId, String stageId, String taskId, String approvalType, Object rejectInfo) {
        if (Constants.APPROVAL_BTO.equals(approvalType)) {
            btoOrderStateService.updateOrSaveOrderState(orderId, BizStageEnum.CONSTRUCT.getStageId(), taskId,
                    BizTaskStateEnum.APPROVAL_REJECT_BTO.getStateId(),
                    BizTaskStateEnum.WAITING_APPROVAL_BTO.getStateId(), true);
            //设备信息-只要有一个拒绝-显示拒绝
            if(taskId.contains(BizTaskEnum.TASK_SBXX.getTaskId())){
                updateConstructSBXXState(orderId , BizTaskStateEnum.APPROVAL_REJECT_BTO.getStateId());
            }

            btoOrderStateService.updateOrSaveOrderState(orderId, BizStageEnum.CONSTRUCT.getStageId(), this.stageId,
                    BizTaskStateEnum.APPROVAL_REJECT_BTO.getStateId(),
                    BizTaskStateEnum.APPROVAL_REJECT_BTO.getStateId(),
                    BizTaskStateEnum.WAITING_APPROVAL_BTO.getStateId());
        }
        //越秀施工信息，审核拒绝
        else if (Constants.APPROVAL_LEASE.equals(approvalType)) {
            btoOrderStateService.updateOrSaveOrderState(orderId, BizStageEnum.CONSTRUCT.getStageId(), this.stageId,
                    BizTaskStateEnum.APPROVAL_REJECT_LEASE.getStateId(),
                    BizTaskStateEnum.WAITING_APPROVAL_LEASE.getStateId(), true);
            //TODO 是否可以根据具体的施工信息，只回退部分任务，拒绝状态。越秀可能会任务初设评审相关信息不对，要触发设计变更
            updateAllConstructInfoLeaseApprovalState(orderId, BizTaskStateEnum.APPROVAL_REJECT_LEASE.getStateId());
        }


    }


    /**
     * 更新所有施工信息-越秀审核状态
     * 越秀”通过、拒绝
     */
    private void updateAllConstructInfoLeaseApprovalState(String orderId, String stateId) {
        //施工信息
        btoOrderStateService.updateOrSaveOrderState(orderId, BizStageEnum.CONSTRUCT.getStageId(), BizTaskEnum.TASK_SGXX.getTaskId(),
                stateId, BizTaskStateEnum.WAITING_APPROVAL_LEASE.getStateId(), true);
        //设备信息
        btoOrderStateService.updateOrSaveOrderState(orderId, BizStageEnum.CONSTRUCT.getStageId(), BizTaskEnum.TASK_SBXX.getTaskId(),
                stateId, BizTaskStateEnum.WAITING_APPROVAL_LEASE.getStateId(), true);
        //施工影像
        btoOrderStateService.updateOrSaveOrderState(orderId, BizStageEnum.CONSTRUCT.getStageId(), BizTaskEnum.TASK_SGYXJXX.getTaskId(),
                stateId, BizTaskStateEnum.WAITING_APPROVAL_LEASE.getStateId(), true);
        //备案证信息
        btoOrderStateService.updateOrSaveOrderState(orderId, BizStageEnum.BAZING.getStageId(), BizTaskEnum.TASK_BAZXX.getTaskId(),
                stateId, BizTaskStateEnum.WAITING_APPROVAL_LEASE.getStateId(), true);
    }

    /**
     * 施工所有状态转为待审核-博通
     */
    private void updateAllConstructStateWaitingApprovalBto(String orderId) {
        for (String taskId : allConstructTasks) {
            OrderState orderTaskState = btoOrderStateService.getOrderTaskState(orderId, this.stageId, taskId);
            if (NullUtils.isNotNull(orderTaskState)) {
                // 填写OK 转为 待博通审核
                if (BizTaskStateEnum.FILLED_OK.getStateId().equalsIgnoreCase(orderTaskState.getStateId())) {
                    btoOrderStateService.updateOrderTaskState(orderId, this.stageId, taskId, BizTaskStateEnum.WAITING_APPROVAL_BTO.getStateId());
                }
                //已经通过的不予处理
                else if (BizTaskStateEnum.APPROVAL_PASS_BTO.getStateId().equalsIgnoreCase(orderTaskState.getStateId())) {

                }
                //已经是待审核不予处理
                else if (BizTaskStateEnum.WAITING_APPROVAL_BTO.getStateId().equalsIgnoreCase(orderTaskState.getStateId())) {

                }
                //其他状态转换 - 报错
                else {
                    throw new BizException("订单{} 施工 任务 {} 当前状态 {} 不允许转为 待博通审核", orderId, taskId, orderTaskState.getStateId());
                }
            }
        }

        //备案证
        OrderState orderTaskState = btoOrderStateService.getOrderTaskState(orderId, BizStageEnum.BAZING.getStageId(), BizTaskEnum.TASK_BAZXX.getTaskId());
        if (NullUtils.isNotNull(orderTaskState)) {
            // 填写OK 转为 待博通审核
            if (BizTaskStateEnum.FILLED_OK.getStateId().equalsIgnoreCase(orderTaskState.getStateId())) {
                btoOrderStateService.updateOrderTaskState(orderId, BizStageEnum.BAZING.getStageId(), BizTaskEnum.TASK_BAZXX.getTaskId(), BizTaskStateEnum.WAITING_APPROVAL_BTO.getStateId());
            }
            //已经通过的不予处理
            else if (BizTaskStateEnum.APPROVAL_PASS_BTO.getStateId().equalsIgnoreCase(orderTaskState.getStateId())) {
            }
            //已经是待审核不予处理
            else if (BizTaskStateEnum.WAITING_APPROVAL_BTO.getStateId().equalsIgnoreCase(orderTaskState.getStateId())) {
            }
            //其他状态转换 - 报错
            else {
                throw new BizException("订单{} 备案证 任务 {} 当前状态 {} 不允许转为 待博通审核", orderId, BizTaskEnum.TASK_BAZXX.getTaskId(), orderTaskState.getStateId());
            }
        }

    }


    /**
     * 检查所有施工信息状态
     */
    public boolean checkAllConstructInfoState(String orderId, String stateId) {
        //施工信息
        val sgxxOrderState = btoOrderStateService.getOrderState(orderId, BizStageEnum.CONSTRUCT.getStageId(), BizTaskEnum.TASK_SGXX.getTaskId(),
                stateId);
        //设备信息
        val sbxxOrderState = btoOrderStateService.getOrderState(orderId, BizStageEnum.CONSTRUCT.getStageId(), BizTaskEnum.TASK_SBXX.getTaskId(),
                stateId);
        //施工影像
        val sgyxOrderState = btoOrderStateService.getOrderState(orderId, BizStageEnum.CONSTRUCT.getStageId(), BizTaskEnum.TASK_SGYXJXX.getTaskId(),
                stateId);
        //备案证信息--(更改阶段)
        val bazxxOrderState = btoOrderStateService.getOrderState(orderId, BizStageEnum.BAZING.getStageId(), BizTaskEnum.TASK_BAZXX.getTaskId(),
                stateId);

        return !NullUtils.isAnyNull(sgxxOrderState, sbxxOrderState, sgyxOrderState, bazxxOrderState);
    }


    /**
     * 设备信息填写完成的状态变更
     */
    public void updateConstructSBXXState(String orderId, String sbxxTaskState) {
        //所有设备信息，填写完毕，触发设备-填写ok
        btoOrderStateService.updateOrSaveOrderState(orderId, BizStageEnum.CONSTRUCT.getStageId(), BizTaskEnum.TASK_SBXX.getTaskId(),
                sbxxTaskState,
                BizTaskStateEnum.FILLED_OK.getStateId(),
                BizTaskStateEnum.WAITING_FILLED.getStateId(),
                BizTaskStateEnum.WAITING_APPROVAL_BTO.getStateId(),
                BizTaskStateEnum.APPROVAL_REJECT_BTO.getStateId(),
                BizTaskStateEnum.APPROVAL_REJECT_LEASE.getStateId());
    }


    /**
     * 检查所有施工设备是否填写Ok或者审批通过
     */
    private boolean checkAllConstructDeviceInfoFilledOk(String orderId) {
        for (String taskId : allConstructSBXXTasks) {
            if (StringUtils.isNotEmpty(taskId)) {
                OrderState orderTaskState = btoOrderStateService.getOrderTaskState(orderId, this.stageId, taskId);
                if (!BizTaskStateEnum.FILLED_OK.getStateId().equals(orderTaskState.getStateId()) &&
                        !BizTaskStateEnum.APPROVAL_PASS_BTO.getStateId().equals(orderTaskState.getStateId())) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 检查所有施工设备是否符合查询状态
     */
    private boolean checkAllConstructDeviceInfoState(String orderId, String stateId) {
        for (String taskId : allConstructSBXXTasks) {
            if (StringUtils.isNotEmpty(taskId)) {
                OrderState orderTaskState = btoOrderStateService.getOrderTaskState(orderId, this.stageId, taskId);
                if (!stateId.equals(orderTaskState.getStateId())) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * 更新施工阶段任务状态
     * 备案证和施工一起
     */
    private void updateAllConstructState(String orderId, String stateId, String... taskIds) {
        //施工相关状态变更
        for (String taskId : taskIds) {
            btoOrderStateService.updateOrderTaskState(orderId, this.stageId, taskId, stateId);
        }
        //备案证
        btoOrderStateService.updateOrderTaskState(orderId, BizStageEnum.BAZING.getStageId(), BizTaskEnum.TASK_BAZXX.getTaskId(), stateId);


    }


}
